package wtx.geek;

import java.util.*;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.Future;

import com.google.common.base.Joiner;
import javafx.util.Pair;
import sun.plugin.dom.exception.InvalidStateException;

/**
 * given input array: [a1, a2, a3, ... an, b1, b2, b3, ..., bn]
 * exchange element in place to get
 * [a1, b1, a2, b2, ..., an, bn]
 */

public class Solution {
    public static String[] exchangeArray(int n) {
        if (n <= 0) {
            return null;
        }
        String[] out = new String[2*n];
        for (int i = 0; i < n; ++i) {
            out[i] = "a" + i;
            out[i+n] = "b" + i;
        }
        exchangeArray(out, 0, 2*n);
//        reArrange(out);
        return out;
    }
    public static void reArrange(String[] a){
        int count=0,start=1,i=start,N=a.length-1;
        String temp=a[start];
        boolean notBreak=true;
        while(notBreak){
            int newPos = (2*i)%N;
            String t = temp;
            temp = a[newPos];
            a[newPos] = t;
            i = newPos;
            count++;
            if(start==i){
                if(count==N-1) {
                    notBreak = false;
                }
                start+=2;
                temp=a[start];
                i=start;
            }
        }
    }
    private static void swap(String[] array, int left, int right) {
        int mid = (right-left)/2;
        for (int i = 0; i < mid; ++i) {
            String tmp = array[left+i];
            array[left+i] = array[mid+left+i];
            array[mid+left+i] = tmp;
        }
    }

    /**
     * Use divide and conquer for O(nlog(n)).
     * This is faster than O(n) in-place transposes on real hardware because of caching effects
      * @param array
     * @param left
     * @param right
     */
    private static void exchangeArray(String[] array, int left, int right) {
        int N = right - left;
        if (N == 2) {
            return;
        }
        int quater = N/4;
        int mid = (right+left)/2;
        swap(array, left + quater, right - quater);
        if ((mid-left)%2 == 1) {
            // odd number
            exchangeArray(array, left, mid-1);
            exchangeArray(array, mid+1, right);
            swap(array, mid-1, mid+1);
        } else {
            exchangeArray(array, left, mid);
            exchangeArray(array, mid, right);
        }
    }
    public static void main(String[] args) {
//        System.out.println(Joiner.on(", ").join(exchangeArray(10)));
        ForkJoinTask f = ForkJoinPool.commonPool().submit(() -> {
            try {
                Thread.sleep(1000);
            } catch (Exception ex) {
                ex.printStackTrace(System.err);
            }
            System.err.println("try throw from background");
            throw new InvalidStateException("throw from background");
        });
        try {
            Thread.sleep(1500);
            System.out.println("done!");
//            throw new InvalidStateException("throw from main");
            f.get();
            if (f.isDone()) {
                System.out.println("background done");
            }
        } catch (Exception ex) {
            ex.printStackTrace(System.err);
            if (f.isCompletedAbnormally()) {
                System.out.println("background isCompletedAbnormally");
            } else if (f.isCompletedNormally()) {
                System.out.println("background isCompletedNormally");
            }
        }

    }
}
